package ua.yandex.books;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 *
 * @author Mitya
 */
public class GenericCollections {

    public static Map<String, List<Book>> groupBookByAuthors(List<Book> books) {

        Map<String, List<Book>> authorMap = new TreeMap<>();

        for (Book book : books) {

            List<String> authorsList = book.getAuthors();
            for (String author : authorsList) {
                if (authorMap.containsKey(author)) {
                    authorMap.get(author).add(book);
                } else {
                    authorMap.put(author, new ArrayList<Book>());
                    authorMap.get(author).add(book);
                }
            }
        }
        return authorMap;
    }

    public static Map<Integer, Set<String>> findTopAuthorsPerEachYear(List<Book> books) {

        Map<Integer, Set<String>> resultingMap = new TreeMap<>();
        Map<Integer, List<Book>> yearMap = new TreeMap<>();

        for (Book book : books) {
            if (!yearMap.containsKey(book.getYearOfPublishing())) {
                yearMap.put(book.getYearOfPublishing(), new ArrayList<Book>());
            }

            yearMap.get(book.getYearOfPublishing()).add(book);
        }

        for (Map.Entry<Integer, List<Book>> yearEntry : yearMap.entrySet()) {
            resultingMap.put(yearEntry.getKey(), new TreeSet<String>());
            Map<String, List<Book>> authorMap = new TreeMap<>();
            List<Book> listOfBooksPerYear = yearEntry.getValue();
            for (Book book : listOfBooksPerYear) {
                for (String author : book.getAuthors()) {
                    if (!authorMap.containsKey(author)) {
                        authorMap.put(author, new ArrayList<Book>());
                    }

                    authorMap.get(author).add(book);
                }
            }

            int maxNumber = 0;

            for (String author : authorMap.keySet()) {
                if (authorMap.get(author).size() > maxNumber) {
                    maxNumber = authorMap.get(author).size();
                }
            }

            for (String author : authorMap.keySet()) {
                if (authorMap.get(author).size() == maxNumber) {
                    resultingMap.get(yearEntry.getKey()).add(author);
                }
            }

        }
        return resultingMap;
    }

    public static Set<Tuple<Topic, List<String>>> findTopicsWithTheMostNumberOfBooks(List<Book> books) {

        Map<Topic, List<Book>> topicMap = new HashMap<Topic, List<Book>>();

        for (Topic topic : Topic.values()) {
            topicMap.put(topic, new ArrayList<Book>());
        }

        for (Book book : books) {

            topicMap.get(book.getTopic()).add(book);
        }

        int maxFrequncy = 0;
        for (Map.Entry<Topic, List<Book>> entryKey : topicMap.entrySet()) {
            if (entryKey.getValue().size() > maxFrequncy) {
                maxFrequncy = entryKey.getValue().size();
            }
        }

        Set<Tuple<Topic, List<String>>> topicSet = new HashSet<>();

        for (Topic key : topicMap.keySet()) {
            if (topicMap.get(key).size() == maxFrequncy) {
                Tuple<Topic, List<String>> tuple = new Tuple(key, topicMap.get(key));
                topicSet.add(tuple);
            }
        }

        return topicSet;
    }
}
